﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MemoryTraceFactory.cs" company="AzureContrib (Open source library http://azurecontrib.codeplex.com)">
//   Microsoft Public License (Ms-PL)
// </copyright>
// <summary>
//   For simplicity this implementation is supplied. It is a valid <see cref="ITraceFactory"/> and it will produce <see cref="MemoryTrace"/> instances.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Diagnostics.CodeAnalysis;

namespace AzureContrib.WindowsAzure.Diagnostics.Testing
{
	/// <summary>
	/// For simplicity this implementation is supplied. It is a valid <see cref="ITraceFactory"/> and it will produce <see cref="MemoryTrace"/> instances.
	/// </summary>
	/// <remarks>>Useful for testing but not incredibly useful for real apps running live.</remarks>
	public sealed class MemoryTraceFactory : ITraceFactory
	{
		/// <summary>
		/// The default name for a default memory trace used mostly for testing.
		/// </summary>
		public const string DefaultMemoryTraceSwitch = "Default memory trace";

		private readonly LogLevel logLevel;

		/// <summary>
		/// Initializes a new instance of the <see cref="MemoryTraceFactory"/> class.
		/// </summary>
		/// <remarks>>Useful for testing but not incredibly useful for real apps running live.</remarks>
		public MemoryTraceFactory()
		{
			logLevel = LogLevel.Verbose;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="MemoryTraceFactory"/> class.
		/// </summary>
		/// <param name="logLevel">A custom <see cref="LogLevel"/> to use for traces from this <see cref="ITraceFactory"/>.</param>
		/// <remarks>>Useful for testing but not incredibly useful for real apps running live.</remarks>
		public MemoryTraceFactory(LogLevel logLevel)
		{
			this.logLevel = logLevel;
		}

		/// <summary>
		/// Gets a new instance of the class <see cref="MemoryTrace"/>.
		/// </summary>
		/// <returns>The instance of the <see cref="MemoryTrace"/> with <see cref="TraceBase.Switch"/> set to <see cref="DefaultMemoryTraceSwitch"/>.</returns>
		/// <remarks>This is not the recommended usage. <seealso cref="CreateDefaultTrace(LogLevel)"/></remarks>
		public static MemoryTrace CreateDefaultTrace()
		{
			return new MemoryTraceFactory().Create(DefaultMemoryTraceSwitch) as MemoryTrace;
		}

		/// <summary>
		/// Gets a new instance of the class <see cref="MemoryTrace"/>.
		/// </summary>
		/// <param name="logLevel">The current level to log at.</param>
		/// <returns>The instance of the <see cref="MemoryTrace"/> with <see cref="TraceBase.Switch"/> set to <see cref="DefaultMemoryTraceSwitch"/>.</returns>
		public static MemoryTrace CreateDefaultTrace(LogLevel logLevel)
		{
			return new MemoryTraceFactory(logLevel).Create(DefaultMemoryTraceSwitch) as MemoryTrace;
		}

		/// <summary>
		/// Gets a new instance of the class <see cref="MemoryTrace"/>.
		/// </summary>
		/// <param name="toLogFor">The type to trace for</param>
		/// <param name="logLevel">The <see cref="LogLevel"/> to log at.</param>
		/// <returns>The instance of the <see cref="MemoryTrace"/> with <see cref="TraceBase.Switch"/> set to <see cref="Type.FullName"/> of <paramref name="toLogFor"/>.</returns>
		public static MemoryTrace CreateTrace(Type toLogFor, LogLevel logLevel)
		{
			return new MemoryTraceFactory(logLevel).Create(toLogFor) as MemoryTrace;
		}

		/// <summary>
		/// Use the type to log for as the name for the logger.
		/// </summary>
		/// <param name="toLogFor">The type to trace for</param>
		/// <returns>A fully loaded <see cref="ITrace"/></returns>
		/// <remarks>The level will be either <see cref="LogLevel.Verbose"/> (good for most testing) or the level sent into the <see cref="MemoryTraceFactory(AzureContrib.WindowsAzure.Diagnostics.LogLevel)"/>. <seealso cref="CreateDefaultTrace(AzureContrib.WindowsAzure.Diagnostics.LogLevel)"/></remarks>
		[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "This is a factory method and thus it should not dispose before returning the instance.")]
		public ITrace Create(Type toLogFor)
		{
			return new MemoryTrace(toLogFor, new CustomLogLevelTraceSwitchProvider(logLevel));
		}

		/// <summary>
		/// Enter a custom switch name for your logger instance.
		/// </summary>
		/// <param name="switch">The swich name</param>
		/// <returns>A fully loaded <see cref="ITrace"/></returns>
		/// <remarks>The level will be either <see cref="LogLevel.Verbose"/> (good for most testing) or the level sent into the <see cref="MemoryTraceFactory(AzureContrib.WindowsAzure.Diagnostics.LogLevel)"/>. <seealso cref="CreateDefaultTrace(AzureContrib.WindowsAzure.Diagnostics.LogLevel)"/></remarks>
		[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "This is a factory method and thus it should not dispose before returning the instance.")]
		public ITrace Create(string @switch)
		{
			return new MemoryTrace(@switch, new CustomLogLevelTraceSwitchProvider(logLevel));
		}
	}
}